//
//  MTLocationManager.m
//  Tazama NGO
//
//  Created by jsheriff on 3/15/11.
//  Copyright 2011 The MITRE Corporation. All rights reserved.
//

#import "MTLocationManager.h"
#import "MTEDXLBuilder.h"
#import "Settings.h"
#import "MTWebServiceClientManager.h"
#import "CoTTypes.h"

@interface MTLocationManager ()

- (void)reportLocation:(NSTimer *)timer;

@end

@implementation MTLocationManager

static MTLocationManager* sharedInstance = nil;

+ (MTLocationManager *)sharedInstance
{
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }
    return sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone
{
    return [[self sharedInstance] retain];
}

- (id)init
{
    if ((self = [super init]))
	{
        updateIntervalInSeconds = 60;
        updateDistanceInMetersActive = 5;
        updateDistinceInMetersInactive = 100;
        
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManager startUpdatingLocation];
        
    }
    return self;
}
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain
{
    return self;
}

- (NSUInteger)retainCount
{
    return NSUIntegerMax;  //denotes an object that cannot be released
}

- (oneway void)release
{
    //do nothing
}

- (id)autorelease
{
    return self;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    lastUpdatedLocation = newLocation;
    
    
    if (!lastUpdateTime) {
        [self reportLocation:nil];
        lastUpdateTime = [[NSDate alloc] init];
    }
    else {
        NSDate *now = [[NSDate alloc] init];
        NSTimeInterval diff = [now timeIntervalSinceDate:lastUpdateTime];
        
        if (diff > updateIntervalInSeconds) {
            [self reportLocation:nil];
            lastUpdateTime = [[NSDate alloc] init];
        }
        
        [now release];
    }
}

- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error {
    
}

- (CLLocation *)currentLocation {
    return locationManager.location;
}

- (void)startPeriodicReporting {
    //Start reporting, then schedule the timed instance
    //[self reportLocation:nil];
    
    [NSTimer scheduledTimerWithTimeInterval:updateIntervalInSeconds target:self selector:@selector(reportLocation:) userInfo:nil repeats:YES];
}

- (void)applicationClosed:(BOOL)updateLoc {
    if (updateLoc) {
        [locationManager startUpdatingLocation];
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
        locationManager.distanceFilter = updateDistinceInMetersInactive;
        [self reportLocation:nil];
        lastUpdateTime = [[NSDate alloc] init];
    }
    else {
        [locationManager stopUpdatingLocation];
    }
}

- (void)applicationOpened:(BOOL)updateLoc {
    if (updateLoc) {
        [locationManager startUpdatingLocation];
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        locationManager.distanceFilter = updateDistanceInMetersActive;
        [self reportLocation:nil];
        lastUpdateTime = [[NSDate alloc] init];
    }
    else {
        [locationManager stopUpdatingLocation];
    }
}
- (void)setUpdateFlag:(BOOL)flag {
    if (flag) {
        [self applicationOpened:YES];
    }
    else {
        [locationManager stopUpdatingLocation];
    }
}

- (void)reportLocation:(NSTimer *)timer {
    // Get the current location
    CLLocation *location = [[MTLocationManager sharedInstance] currentLocation];
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    BOOL sendReport = [defaults boolForKey:kSendPositionReport];
    
    if (location && sendReport) {
        // Build the CoT content object
        NSString *userId = [defaults objectForKey:kUserId];
        
        if (userId == nil || userId.length == 0) {
            NSLog(@"User ID not found");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-mail Not Found" message:@"Please enter your e-mail in the settings" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert show];
            [alert release];
            return;
        }
        
        //NSString *uid = [NSString stringWithFormat:@"ICNET:%@", userId];
        NSString *coTTypeStr = [defaults objectForKey:currCoTType];
        if (coTTypeStr == nil || coTTypeStr.length == 0) {
            NSLog(@"Cot Type not found");
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unit Type Not Found" message:@"Unit type not found. Please select a unit type from the settings" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert show];
            [alert release];
            return;
        }
        NSString *uniqueIDStr = [defaults objectForKey:uniqueID];
        if (uniqueIDStr == nil || uniqueIDStr.length == 0) {
            NSLog(@"UUID Not Found");
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unit Unique ID Not Found" message:@"Unit unique ID not found. Please enter a unit ID from the settings" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert show];
            [alert release];
            return;
        }
        
        CoTTypes *cotTypes = [[CoTTypes alloc] init];
        CoTType *cotType = [cotTypes getCoTTypeByCoTType:coTTypeStr];
        NSString *cotUniqueId = [NSString stringWithFormat:@"%@%@", [cotType unitAbbreviation], uniqueIDStr];
        
        
        NSString *sitRepKeywordStr = [defaults objectForKey:sitrepKeyword];
        if (sitRepKeywordStr == nil || sitRepKeywordStr.length == 0) {
            sitRepKeywordStr = @"MobileReport";
        }
        NSString *posKeywordStr = [defaults objectForKey:posKeyword];
        if (posKeywordStr == nil || posKeywordStr.length == 0) {
            posKeywordStr = @"MobileUnit";
        }
        
        NSDate *today = [NSDate date];
        
        NSTimeInterval oneMinuteSeconds = 60;
        NSTimeInterval oneHourSeconds = oneMinuteSeconds*60;
        NSTimeInterval oneDaySeconds = oneHourSeconds * 24;
        NSDate *stale = [today dateByAddingTimeInterval:oneDaySeconds];
        
        NSString *cotContentObject = [MTEDXLBuilder createCotContentObjectWithType:coTTypeStr positionKeyword:posKeywordStr srpKeyword:sitRepKeywordStr  uid:cotUniqueId how:@"m-g" time:today start:today stale:stale location:location.coordinate];

        // Put the CoT content object in an array
        NSMutableArray *contentObjectArray = [[NSMutableArray alloc] init];
        [contentObjectArray addObject:cotContentObject];
        
        // Build the EDXL DE st
        NSString * distributionId = [NSString stringWithFormat:@"CoT Incident - %@", userId];
        NSString *edxl = [MTEDXLBuilder createDistributionElementWithId:distributionId senderId:userId dateTimeSent:[NSDate date] distributionStatus:@"Test" location:location.coordinate distributionType:@"Update" combinedConfidentiality:@"Unclass" language:@"en-US" contentObjects:contentObjectArray];
        
        [contentObjectArray release];
        
        // Send the message to the server
        NSString *hostName = [defaults objectForKey:kHostName];
        
        if (hostName == nil || hostName.length == 0)
        {
            NSLog(@"Host Name not found");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Host Name Not Found" message:@"Host name for posting not found. Please enter a valid post URL in settings" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert show];
            [alert release];
            return;
        }
        
        NSLog(@"Updating Location (CoT), sending web service request to host: %@", hostName);
        
        CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
        NSString *url;
        if ([defaults objectForKey:kPort]) {
            if ([hostName rangeOfString:@"http://"].location == NSNotFound) {
                url = [NSString stringWithFormat:@"http://%@:%@/PostDE", hostName, [defaults objectForKey:kPort]];
            }
            else {
                url = [NSString stringWithFormat:@"%@:%@/PostDE", hostName, [defaults objectForKey:kPort]];
            }
        }
        else {
            if ([hostName rangeOfString:@"http://"].location == NSNotFound) {
                url = [NSString stringWithFormat:@"http://%@/PostDE", hostName];
            }
            else {
                url = [NSString stringWithFormat:@"%@/PostDE", hostName];
            }
        }
        [[MTWebServiceClientManager sharedManager] postRequestWithId:uuid toUrl:url message:edxl retry:NO];
        
    }
}

@end
